/**
	Modificacao sutil do word data reader
	(veja comentarios la')
	A unica diferenca e' que as frases
	sao coletadas antes de serem
	processadas (para colher palavras)

	A frase final (limpa) e' a concatenacao
	das palavras coletadas, separadas por
	espacos,
	nao contendo, portanto,
	virgulas, pontuacoes, etc.
**/


#include <PhraseDataReader.hpp>
#include <fstream>
#include <string>
#include <cstdio>
#include <map>
#include <cstring>

PhraseDataReader::PhraseDataReader
(std::string filename)
: filename(filename) {

}

std::vector<std::pair<std::string, unsigned> >*
PhraseDataReader::readData() {
	// std::fstream file(filename.c_str(), std::fstream::in);
	FILE * file;
	file = fopen (filename.c_str(), "r");

	char buffer[1024];
	char line[4096];
	const char *c;
	// std::string line;
	std::string phrase;
	std::string str;
	int length;

	std::map<std::string, int> m;

	std::vector<std::pair<std::string, unsigned> >* v =
		new std::vector<std::pair<std::string, unsigned> > ();

	// while (std::getline(file, line, '\n')) {

	fscanf(file, "%*[\r\n]");
	while (fscanf(file, "%[^\r\n]", line) != EOF) {
		fscanf(file, "%*[\r\n]");
		// c = line.c_str();
		length = strlen(line);
		c = line;

		//essa é a frase final, limpa ela no começo do loop porque ela foi
		//usada na iteração anterior
		phrase.clear();
		int begin = 0;

		//procura o primeiro caracter da linha que está em [a-zA-Z] e guarda
		//o índice dele em begin -- o começo da primeira palavra da linha
		for(int i = 0;
			c[i] &&
			!(
					(c[i] >= 'a' && c[i] <= 'z') 
				||	(c[i] >= 'A' && c[i] <= 'Z')
				/*|| c[i] == '-'*/
			); 
			i++, begin++
		);

		//faz o loop a partir da primeira palavra de verdade da linha
		while (begin < length) {
			//lê a palavra que está na posição &c[begin]
			sscanf(c + begin, "%1023[A-Za-z]",
				buffer);

			//busca o primeiro caracter que não está em [a-zA-Z] e guarda o
			//índice dela em ccount -- o caracter imediatamente depois do fim
			//da palavra
			int ccount = 0;
			for(int i = begin;
				c[i] &&
				(
						(c[i] >= 'a' && c[i] <= 'z')
					||	(c[i] >= 'A' && c[i] <= 'Z')
					/*|| c[i] == '-'*/
				);
				i++, ccount++);

			begin += ccount;

			//busca o começo da próxima palavra, ignorando qualquer coisa que
			//não está em [a-zA-Z]
			ccount = 0;
			for(int i = begin;
				c[i] &&
				!(
						(c[i] >= 'a' && c[i] <= 'z') 
					||	(c[i] >= 'A' && c[i] <= 'Z')
					 /*|| c[i] == '-'*/)
				; i++, ccount++
			);
			begin += ccount;

			//guarda a palavra que foi lida pra poder salvar na variável da
			//frase mais fácil
			str = buffer;

			//conta quantas ocorrências da palavra tem no texto, pula palavras
			//de uma letra só
			if (str.size() > 1) {
				std::map<std::string, int>::iterator it;
				it = m.find(str);
				if (it == m.end()) {
					//salva a nova palavra lida com uma contagem de 1
					v->push_back(std::pair<std::string, unsigned>
						(str, 1));
					m[str] = v->size() - 1;
				} else {
					(*v)[it->second].second++;
				}
			}

			//coloca a palavra na frase, as palavras ficam separadas por
			//um único espaço
			if (!phrase.empty())
				phrase += ' ';
			phrase += str;
		}
		//guarda quantas ocorrências da frase aparecem no texto
		if (!phrase.empty()) {
			std::map<std::string, int>::iterator it;
			it = m.find(phrase);
			if (it == m.end()) {
				//salva a frase com ocorrência 1
				v->push_back(std::pair<std::string, unsigned>
					(phrase, 1));
				m[phrase] = v->size() - 1;
			} else {
				(*v)[it->second].second++;
			}
		}
	}


	// file.close();
	fclose(file);
	return v;
}
